package caj.springboot;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;


import java.nio.file.Paths;
import java.sql.Types;
import java.util.*;

/**
 * @description: mybatis-plus代码生成器
 * @author: CAJ
 * @time: 2024/12/28 16:28
 */
public class CodeGenerator {
    public static void main(String[] args) {
// 设置数据库连接
        FastAutoGenerator.create("jdbc:postgresql://127.0.0.1:5432/springboot-template", "postgres", "postgres")
//        FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/springboot-template?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai", "root", "root")
                // 全局配置提供了对代码生成器整体行为的设置
                .globalConfig(builder -> {
                    builder.author("caj") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .commentDate("yyyy-MM-dd HH:mm:ss")
                            .outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java"); // 指定输出目录
//                  Paths.get(System.getProperty("user.dir")) 是 Java 中用于获取当前项目目录的路径。
                })
                // 自定义数据库字段类型到 Java 字段类型的转换规则。
                .dataSourceConfig(builder ->
                        builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                            int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                            // 解决mysql中tinyint无法转换的问题
                            if (typeCode == Types.SMALLINT) {
                                // 自定义类型转换
                                return DbColumnType.INTEGER;
                            }
                            return typeRegistry.getColumnType(metaInfo);
                        })
                )
                // 包配置，设置生成代码的位置
                .packageConfig(builder ->
                        builder.parent("caj.springboot") // 设置父包名
//                                .moduleName("") // 设置父包模块名
                                .entity("model.po.name")
                                .service("service.name")
                                .serviceImpl("service.name.impl")
                                .controller("controller.name")
                                .mapper("mapper")
                                .xml("mapper")
                                .pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir")+"\\src\\main\\resources\\mapper")) // 设置mapperXml生成路径
                )
                .strategyConfig(builder ->
                        builder.addInclude("tbl_name") // 设置需要生成的表名
//                                .addInclude("tbl_name", "c_simple1") // 设置需要生成的多个表名
                                .addTablePrefix("tbl_", "c_") // 设置过滤表前缀
                                .entityBuilder()
                                .disableSerialVersionUID() // 去除实现序列化接口
//                                .superClass(BaseModel.class) // 继承类
                                .enableLombok() // 启用 Lombok
                                .javaTemplate("/templates/entity.java") // 设置实体类模板
                                .controllerBuilder()
                                .enableRestStyle() // 开启生成@RestController 控制器
                                .template("/templates/controller.java")
                                .mapperBuilder()
                                .mapperTemplate("/templates/mapper.java")
                                .serviceBuilder()
                                .formatServiceFileName("%sService") // 去掉前缀I
                                .serviceTemplate("/templates/service.java")
                                .serviceImplTemplate("/templates/serviceImpl.java")
                                .build()
                )
                // 自定义配置
                .injectionConfig(injectConfig -> {
                    // 创建自定义变量映射
                    Map<String, Object> customMap = new HashMap<>();
                    customMap.put("VO", "caj.springboot.model.vo.name"); // VO包名
                    customMap.put("DTO", "caj.springboot.model.dto.name"); // DTO包名
                    customMap.put("MapStruct", "caj.springboot.model.mapstruct"); // MapStruct包名
                    injectConfig.customMap(customMap);

                    // 添加VO文件配置
                    injectConfig.customFile(new CustomFile.Builder()
                            .fileName("VO.java")
                            .templatePath("/templates/vo.java.ftl")
                            .packageName("model.vo.name") // 这里应该是完整的包路径
                            .build());

//                    // 添加DTO文件配置
//                    injectConfig.customFile(new CustomFile.Builder()
//                            .fileName("DTO.java")
//                            .templatePath("/templates/dto.java.ftl")
//                            .packageName("model.dto.name")
//                            .build());

                    // 添加InsertDTO文件配置
                    injectConfig.customFile(new CustomFile.Builder()
                            .fileName("InsertDTO.java")
                            .templatePath("/templates/insertdto.java.ftl")
                            .packageName("model.dto.name")
                            .build());

                    // 添加UpdatedDTO文件配置
                    injectConfig.customFile(new CustomFile.Builder()
                            .fileName("UpdateDTO.java")
                            .templatePath("/templates/updatedto.java.ftl")
                            .packageName("model.dto.name")
                            .build());

                    // 添加SearchDTO文件配置
                    injectConfig.customFile(new CustomFile.Builder()
                            .fileName("SearchDTO.java")
                            .templatePath("/templates/searchdto.java.ftl")
                            .packageName("model.dto.name")
                            .build());

                    // 添加Converter文件配置
                    injectConfig.customFile(new CustomFile.Builder()
                            .fileName("ConverterMapper.java")
                            .templatePath("/templates/converter.java.ftl")
                            .packageName("model.mapstruct")
                            .build());

                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .execute();
    }
}
